package com.office.automate.frontier.utility;

import java.text.DateFormat;
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;

import com.office.automate.configuration.property.ConfigurationProperties;

public class DataConversionUtility {

	private Properties configProp = ConfigurationProperties.getProps();
	/**
	 * This method will return integer number for the
	 * given number string. If the given string cannot
	 * convert to number, then this method will return
	 * zero.
	 * @param aNumber
	 * @return int
	 */
	public int convertStringToNumber(String aNumber) {
		try {
			return Integer.parseInt(aNumber);
		} catch (Exception e) {
			return 0;
		}
	}

	public long convertStringToLong(String aNumber) {
		try {
			return Long.parseLong(aNumber);
		} catch (Exception e) {
			return 0;
		}
	}

	public double convertStringToDouble(String aNumber) {
		try {
			return Double.parseDouble(aNumber);
		} catch (Exception e) {
			return (double)0;
		}
	}

	public boolean convertStringToBoolean(String aBoolean) {
		try {
			return Boolean.parseBoolean(aBoolean);
		} catch (Exception e) {
			return false;
		}
	}
	
	/**
	 * This method will return the description of the
	 * given Date object.
	 *  
	 * @param aMonth
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public String getMonthDescription(Date aDate) {
		return new DateFormatSymbols().getMonths()[aDate.getMonth()];
	}

	public String getMonthDescription(int aDate) {
		return new DateFormatSymbols().getMonths()[aDate];
	}

	public boolean isNotNull(String aValue) {
		return (aValue == null) ? false: true;
	}

	public int getPersistance(String aValue) {
		return (aValue == null) ? 0: 1;
	}

	public int convertToNumber(String aNumber) {
		try {
			return Integer.parseInt(aNumber);
		} catch (Exception e) {
			return -1;
		}
	}

	public long convertToLong(String aNumber) {
		try {
			return Long.parseLong(aNumber);
		} catch (Exception e) {
			return -1;
		}
	}

	public double convertToDouble(String aNumber) {
		try {
			return Double.parseDouble(aNumber);
		} catch (Exception e) {
			return (double)-1;
		}
	}

	public Date convertToDate(String aDate) {
		try {
			DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
			return dateFormat.parse(aDate);
		} catch (Exception e) {
			return new Date(0);
		}
	}

	public String replaceWord(String original, String find, String replacement) {
	    int i = original.indexOf(find);
	    if (i < 0) {
	        return original;  // return original if 'find' is not in it.
	    }

	    String partBefore = original.substring(0, i);
	    String partAfter  = original.substring(i + find.length());
	  
	    return partBefore + replacement + partAfter;
	}

	public int getWorkingDaysCountForGivenDateRange(Date aRangeStartDate, Date aRangeEndDate) {
		int count = 0;
		count = calculateNumberOfDaysExcludeWeekends(aRangeStartDate, aRangeEndDate);
		return count;
	}

	public int calculateNumberOfDaysExcludeWeekends(Date startDate, Date endDate) {

	    Calendar calendar = Calendar.getInstance();
	    calendar.setTime(startDate);

	    int numOfDays = 0;
	    while(!calendar.getTime().after(endDate)) {
	        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
	        if ( (dayOfWeek>1) && (dayOfWeek<7) ) {
	            numOfDays++;
	        }
	        calendar.add(Calendar.DAY_OF_MONTH, 1);
	    }

	    return numOfDays;
	}

	public static int calculateNumberOfWeekendsInRange(Date startDate, Date endDate) {
	    Calendar calendar = Calendar.getInstance();
	    calendar.setTime(startDate);

	    int counter = 0;
	    while(!calendar.getTime().after(endDate)) {
	        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
	        if (dayOfWeek==1 || dayOfWeek==7) {
	            counter++;
	        }
	        calendar.add(Calendar.DAY_OF_MONTH, 1);
	    }

	    return counter;
	}

	public Date getDatesOfGivenWeek(Date currentDate, int weekDay) {
		Date requestedDate = null;
	    Calendar calendar = Calendar.getInstance();
	    calendar.setTime(currentDate);
	    int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
	    int difference = dayOfWeek - weekDay;
	    
	    if (dayOfWeek == weekDay) {
	    	requestedDate = currentDate;
	    } else if (difference > 0) {
	    	Calendar cal = Calendar.getInstance();
	    	cal.setTime(currentDate);
	    	cal.add(Calendar.DATE, -difference);
	    	requestedDate = cal.getTime();
	    } else {
	    	Calendar cal = Calendar.getInstance();
	    	cal.setTime(currentDate);
	    	cal.add(Calendar.DATE, -difference);
	    	requestedDate = cal.getTime();
	    }	    
		return requestedDate;
	}

	public boolean validateTodayDate(String dateValue) {
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		String todayDate = dateFormat.format(new Date());

		return dateValue.equalsIgnoreCase(todayDate);
	}

	public Date getCurrentBillingDate() {
		Calendar cal1 =Calendar.getInstance();
		cal1.setTime(new Date());
		int year = cal1.get(Calendar.YEAR);
		int month = cal1.get(Calendar.MONTH);
		int day = Integer.parseInt(configProp.getProperty("BILLING_DATE_OF_THE_MONTH"));
		Date billingDate = convertToDate(year+ "-"+(month+1)+"-"+day);
		return billingDate;
	}

	public Date getBillingDateOfPreviousMonth() {
		Calendar cal1 =Calendar.getInstance();
		cal1.setTime(new Date());
		int year = cal1.get(Calendar.YEAR);
		int month = cal1.get(Calendar.MONTH);
		int todayDate = cal1.get(Calendar.DATE);
		int day = Integer.parseInt(configProp.getProperty("BILLING_DATE_OF_THE_MONTH"));
		if (month == Calendar.JANUARY && todayDate < day) {
			year--;
			month = Calendar.DECEMBER;
		}
		Date billingDate = convertToDate(year+ "-"+(month+1)+"-"+day);
		return billingDate;
	}

	public Date getBillingDateOfPreviousMonthForGivenDate(Date currentBillingDate) {
		Calendar cal1 =Calendar.getInstance();
		cal1.setTime(currentBillingDate);
		int year = cal1.get(Calendar.YEAR);
		int month = cal1.get(Calendar.MONTH);
		int day = Integer.parseInt(configProp.getProperty("BILLING_DATE_OF_THE_MONTH"));
		if (month == Calendar.JANUARY) {
			year--;
			month = Calendar.DECEMBER;
		}
		Date billingDate = convertToDate(year+ "-"+(month+1)+"-"+day);
		return billingDate;
	}

	public Date getBillingCycleStartDateOfForGivenDate(Date currentBillingDate) {
		Calendar cal1 =Calendar.getInstance();
		cal1.setTime(currentBillingDate);
		int year = cal1.get(Calendar.YEAR);
		int month = cal1.get(Calendar.MONTH);
		int day = Integer.parseInt(configProp.getProperty("BILLING_DATE_OF_THE_MONTH"));
		if (month == Calendar.JANUARY) {
			year--;
			month = Calendar.DECEMBER;
		} else {
			month--;
		}
		Date billingDate = convertToDate(year+ "-"+(month+1)+"-"+(day+1));
		return billingDate;
	}

	public String getCurentBillingPeriod() {
		String billingPeriod = "";
		DateFormat dateFormat = new SimpleDateFormat("dd/MMM/yyyy");
		Calendar calc = Calendar.getInstance();
		calc.setTime(new Date());
		Date billingDateOfCurrentMonth = convertToDate(calc.get(Calendar.YEAR)+"-"+ (calc.get(Calendar.MONTH)+1)+"-" + configProp.getProperty("BILLING_DATE_OF_THE_MONTH"));
		if (billingDateOfCurrentMonth.after(new Date())) {
			Date billingDateOfPreviousMonth = getBillingDateOfPreviousMonthForGivenDate(new Date());
			Date billingPeriodStartDateOfPreviousMonth = getBillingCycleStartDateOfForGivenDate(billingDateOfPreviousMonth);
			billingPeriod = dateFormat.format(billingPeriodStartDateOfPreviousMonth) + "-" + dateFormat.format(billingDateOfPreviousMonth);
		} else {
			billingPeriod = dateFormat.format(getBillingCycleStartDateOfForGivenDate(billingDateOfCurrentMonth)) + "-" + dateFormat.format(billingDateOfCurrentMonth);
		}
		return billingPeriod;
	}
}
